﻿#pragma once

#include <string>
#include <typeinfo>

enum class EventType
{
  None = 0,
  WindowResize,       // 窗口大小变化
  KeyPressed,         // 按键按下
  KeyReleased,        // 按键释放
  MouseMoved,         // 鼠标移动
  MouseScrolled,      // 鼠标滚动
  MouseButtonPressed, // 鼠标按下
  MouseButtonReleased // 鼠标释放
};

class Event
{
public:
  virtual ~Event() = default;
  virtual EventType GetEventType() const = 0;
  virtual std::string ToString() const { return "BaseEvent"; }
  bool Handled = false; // 标记事件是否已处理
};

// 窗口大小变化事件
class WindowResizeEvent : public Event
{
public:
  WindowResizeEvent(int width, int height) : m_width(width), m_height(height) {}
  static EventType GetStaticEventType() { return EventType::WindowResize; }
  EventType GetEventType() const override { return EventType::WindowResize; }
  std::string ToString() const override
  {
    return "WindowResizeEvent: " + std::to_string(m_width) + "x" + std::to_string(m_height);
  }
  inline int GetWidth() const { return m_width; }
  inline int GetHeight() const { return m_height; }

private:
  int m_width, m_height;
};

// 按键按下事件
class KeyPressedEvent : public Event
{
public:
  KeyPressedEvent(int key, int repeatCount) : m_key(key), m_repeatCount(repeatCount) {}
  static EventType GetStaticEventType() { return EventType::KeyPressed; }
  EventType GetEventType() const override { return EventType::KeyPressed; }
  std::string ToString() const override
  {
    return "KeyPressedEvent: Key=" + std::to_string(m_key) + ", Repeat=" + std::to_string(m_repeatCount);
  }
  inline int GetKey() const { return m_key; }
  inline int GetRepeatCount() const { return m_repeatCount; }

private:
  int m_key;
  int m_repeatCount;
};

// 按键释放事件
class KeyReleasedEvent : public Event
{
public:
  KeyReleasedEvent(int key) : m_key(key) {}
  static EventType GetStaticEventType() { return EventType::KeyReleased; }
  EventType GetEventType() const override { return EventType::KeyReleased; }
  std::string ToString() const override { return "KeyReleasedEvent: Key=" + std::to_string(m_key); }
  inline int GetKey() const { return m_key; }

private:
  int m_key;
};

// 鼠标移动事件
class MouseMovedEvent : public Event
{
public:
  MouseMovedEvent(float x, float y) : m_x(x), m_y(y) {}
  static EventType GetStaticEventType() { return EventType::MouseMoved; }
  EventType GetEventType() const override { return EventType::MouseMoved; }
  std::string ToString() const override
  {
    return "MouseMovedEvent: X=" + std::to_string(m_x) + ", Y=" + std::to_string(m_y);
  }
  inline float GetX() const { return m_x; }
  inline float GetY() const { return m_y; }
  inline glm::vec2 GetPosition() const { return {m_x, m_y}; }

private:
  float m_x, m_y;
};

// 鼠标滚动事件
class MouseScrolledEvent : public Event
{
public:
  MouseScrolledEvent(float xOffset, float yOffset) : m_xOffset(xOffset), m_yOffset(yOffset) {}
  static EventType GetStaticEventType() { return EventType::MouseScrolled; }
  EventType GetEventType() const override { return EventType::MouseScrolled; }
  std::string ToString() const override
  {
    return "MouseScrolledEvent: XOffset=" + std::to_string(m_xOffset) + ", YOffset=" + std::to_string(m_yOffset);
  }
  inline float GetXOffset() const { return m_xOffset; }
  inline float GetYOffset() const { return m_yOffset; }

private:
  float m_xOffset, m_yOffset;
};

// 鼠标按键按下事件
class MouseButtonPressedEvent : public Event
{
public:
  MouseButtonPressedEvent(int button) : m_button(button) {}
  static EventType GetStaticEventType() { return EventType::MouseButtonPressed; }
  EventType GetEventType() const override { return EventType::MouseButtonPressed; }
  std::string ToString() const override { return "MouseButtonPressedEvent: Button=" + std::to_string(m_button); }
  inline int GetButton() const { return m_button; }

private:
  int m_button;
};

// 鼠标按键释放事件
class MouseButtonReleasedEvent : public Event
{
public:
  MouseButtonReleasedEvent(int button) : m_button(button) {}
  static EventType GetStaticEventType() { return EventType::MouseButtonReleased; }
  EventType GetEventType() const override { return EventType::MouseButtonReleased; }
  std::string ToString() const override { return "MouseButtonReleasedEvent: Button=" + std::to_string(m_button); }
  inline int GetButton() const { return m_button; }

private:
  int m_button;
};
